package com.kakarote.examine.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.kakarote.core.common.enums.FieldEnum;
import com.kakarote.core.exception.CrmException;
import com.kakarote.core.feign.crm.entity.ExamineField;
import com.kakarote.core.feign.examine.entity.ExamineConditionDataBO;
import com.kakarote.core.feign.examine.entity.ExamineFlowConditionDataVO;
import com.kakarote.core.feign.examine.entity.ExamineFlowFieldUpdateLogBO;
import com.kakarote.core.feign.examine.entity.ExamineUpdateFieldBO;
import com.kakarote.examine.common.LanguageFieldUtil;
import com.kakarote.examine.constant.ExamineCodeEnum;
import com.kakarote.examine.entity.PO.ExamineFlowAuthField;
import com.kakarote.examine.entity.PO.ExamineFlowFieldUpdateLog;
import com.kakarote.examine.service.ExamineModuleService;
import com.kakarote.examine.service.IExamineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("examineCrmService")
public class ExamineCrmServiceImpl implements ExamineModuleService {

    @Autowired
    private IExamineService examineService;

    /**
     * 查询审批可用的字段
     *
     * @param label      label
     * @param categoryId categoryId
     * @return data
     */
    @Override
    public List<ExamineField> queryExamineField(Integer label, Long categoryId) {
        List<ExamineField> examineFields = new ArrayList<>();
        examineFields.forEach(examineField -> examineField.setFieldName(StrUtil.toCamelCase(examineField.getFieldName())));

        if (CollectionUtil.isNotEmpty(examineFields)) {
            for (ExamineField examineField : examineFields) {
                Map<String, String> keyMap = LanguageFieldUtil.getFieldNameKeyMap("name_resourceKey", "defaultParams.crmExamine" + label + ".", examineField.getFieldName(), examineField.getSetting());
                Map<String, String> remarksKey = LanguageFieldUtil.getFieldNameKeyMap("remarks_resourceKey", "defaultParams.crmExamineRemarks" + label + ".", examineField.getFieldName());
                keyMap.putAll(remarksKey);
                examineField.setLanguageKeyMap(keyMap);
            }
        }
        return examineFields;
    }

    /**
     * 修改审核状态
     *
     * @param label       类型
     * @param typeId      对应类型主键ID
     * @param checkStatus 审核状态 0待审核、1通过、2拒绝、3审核中 4:撤回 5 未提交 6 创建 7 已删除 8 作废
     */
    @Override
    public void updateCheckStatus(Integer label, Long typeId, Integer checkStatus, Object data) {
        ExamineConditionDataBO examineConditionDataBO = new ExamineConditionDataBO();
        examineConditionDataBO.setLabel(label);
        examineConditionDataBO.setTypeId(typeId);
        examineConditionDataBO.setCheckStatus(checkStatus);
        if (ObjectUtil.isNotNull(data)) {
            examineConditionDataBO.setData(data);
        }
    }

    /**
     * 校验当前状态是否可以进行，不可进行直接抛异常即可
     *
     * @param label          类型
     * @param typeId         对应类型ID
     * @param checkStatus    审核状态
     * @param oldCheckStatus 之前的审核状态
     */
    @Override
    public void checkStatus(Integer label, Long typeId, Integer checkStatus, Integer oldCheckStatus) {
        int four = 4;
        if (checkStatus == four) {
            //当前审核已通过不可撤回
            if (oldCheckStatus == 1) {
                throw new CrmException(ExamineCodeEnum.EXAMINE_RECHECK_PASS_ERROR);
            }
        }
    }

    /**
     * 获取条件审核需要的数据entity
     *
     * @param label  类型
     * @param typeId 对应类型ID
     * @return map
     */
    @Override
    public Map<String, Object> getConditionMap(Integer label, Long typeId, Long recordId) {
        ExamineConditionDataBO examineConditionDataBO = new ExamineConditionDataBO();
        examineConditionDataBO.setLabel(label);
        examineConditionDataBO.setTypeId(typeId);
        List<String> fieldList = new ArrayList<>();
        List<ExamineFlowConditionDataVO> conditionDataVoS = examineService.previewFiledName(label, recordId, null);
        if (conditionDataVoS != null) {
            fieldList = conditionDataVoS.stream().map(ExamineFlowConditionDataVO::getFieldName).collect(Collectors.toList());
            fieldList.removeIf(StrUtil::isEmpty);
        }
        examineConditionDataBO.setFieldList(fieldList);
        return new HashMap<>();
    }


    /**
     * 获取成员组件需要的数据entity
     *
     * @param fieldName
     * @param label
     * @param typeId
     * @param recordId
     * @return
     */
    @Override
    public Map<String, Object> getMemberComponentMap(String fieldName, Integer label, Long typeId, Long recordId) {
        ExamineConditionDataBO examineConditionDataBO = new ExamineConditionDataBO();
        examineConditionDataBO.setLabel(label);
        examineConditionDataBO.setTypeId(typeId);
        examineConditionDataBO.setFieldList(CollectionUtil.toList(fieldName));
        return new HashMap<>();
    }


    @Override
    public List<?> getAuthField(List<ExamineFlowAuthField> authFields, Integer label, Long typeId, List<ExamineFlowFieldUpdateLog> updateLogs) {
        List<Map<String, Object>> data = Collections.emptyList();

        if (CollectionUtil.isNotEmpty(authFields)) {
            List<Map<String, Object>> list = new ArrayList<>();
            Map<String, ExamineFlowAuthField> collect = authFields.stream().filter(authField -> authField.getAuthLevel() > 1).collect(Collectors.toMap(
                    e -> StrUtil.toCamelCase(e.getFieldName()), Function.identity(), (k1, k2) -> k1
            ));
            Set<String> keySet = collect.keySet();

            for (Map<String, Object> datum : data) {
                if (keySet.contains(datum.get("fieldName"))) {
                    Object type = datum.get("type");
                    ExamineFlowAuthField authField = collect.get(datum.get("fieldName"));
                    datum.put("authLevel", authField.getAuthLevel());
                    datum.put("tableLevel", authField.getTableLevel() == null ? 0 : authField.getTableLevel());
                    if (FieldEnum.DETAIL_TABLE.getType().equals(type)) {
                        disposeDetailTable(datum, authField.getFieldExtendList());
                    }
                    list.add(datum);
                }
            }

            for (ExamineFlowFieldUpdateLog updateLog : updateLogs) {
                String fieldName = updateLog.getFieldName();
                String newValue = updateLog.getNewValue();
                for (Map<String, Object> datum : list) {
                    if (fieldName.equals(datum.get("fieldName"))) {
                        datum.put("value", convertValueByFormType(newValue, updateLog.getType()));
                    }
                }
            }
            return list;
        }
        data.forEach(map -> {
            map.put("authLevel", 2);
            Object type = map.get("type");
            if (FieldEnum.DETAIL_TABLE.getType().equals(type)) {
                map.put("tableLevel", 0);
            }
        });
        return data;
    }


    @Override
    public void updateFieldInfo(ExamineUpdateFieldBO examineUpdateFieldBO) {

    }

    @Override
    public List<Map<String, Object>> queryExamineUpdateLog(List<ExamineFlowFieldUpdateLogBO> list) {

        return Collections.emptyList();
    }


}
